package com.basker.pisces.context;

import java.util.Locale;

import org.apache.commons.lang3.LocaleUtils;
import org.springframework.util.StringUtils;

import com.basker.pisces.utils.NumberUtils;

/**
 * 登录上下文抽象类，业务产品可以基于其扩展自身需要的属性，该类提供了静态方法用于存储登录上下文.
 *
 * <p>
 * 登录上下文只是一个模型，目的是在框架内可以获取到当前线程对应的用户和其他一些信息（如操作日志、权限等），但这些值的来源需要外部模块负责组装。
 *
 * @author hangwen
 * @see
 */
public abstract class LoginContext {

    private Object userId;
    private String locale;
    private Token token;
    private long timestamp;

    protected LoginContext() {
        this.timestamp = System.currentTimeMillis();
    }

    /**
     * 获取国家语言代码
     *
     * @return
     */
    public String getLocale() {
        return locale;
    }

    /**
     * 获取Locale对象
     *
     * @return
     */
    public Locale getLocaleObject() {
        if (StringUtils.isEmpty(locale)) {
            return null;
        }

        return LocaleUtils.toLocale(locale);
    }

    /**
     * 上下文创建的时间
     *
     * @return
     */
    public final long getTimestamp() {
        return this.timestamp;
    }

    /**
     * 获取令牌
     *
     * @return
     */
    public Token getToken() {
        return token;
    }

    /**
     * 获取当前用户id
     *
     * @return
     */
    public Object getUserId() {
        return userId;
    }

    /**
     * 判断当前用户与传入的用户Id是否一致
     *
     * @param userId
     * @return
     */
    public boolean isTheUser(Object userId) {
        if (this.userId == null) {
            return false;
        }

        if (this.userId instanceof Number) {
            @SuppressWarnings("unchecked")
            Class<? extends Number> numberClass = (Class<? extends Number>) this.userId.getClass();
            return this.userId.equals(NumberUtils.parse(userId, numberClass));
        }

        return String.valueOf(this.userId).equals(String.valueOf(userId));
    }

    /**
     * 设置国家语言代码
     *
     * @param locale
     */
    public void setLocale(String locale) {
        this.locale = locale;
    }

    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }

    /**
     * 设置令牌
     *
     * @param tokenId
     */
    public void setToken(Token token) {
        this.token = token;
    }

    /**
     * 设置当前用户id
     *
     * @param userId
     */
    public void setUserId(Object userId) {
        this.userId = userId;
    }

}
